package com.idealcn.define.view.view

import android.animation.Animator
import android.animation.ValueAnimator
import android.content.Context
import android.graphics.RectF
import android.util.AttributeSet
import android.util.Log
import android.view.Gravity
import android.view.MotionEvent
import android.view.View
import android.view.ViewConfiguration
import android.view.ViewGroup
import android.view.animation.AccelerateInterpolator
import android.view.animation.LinearInterpolator
import android.widget.ImageView
import android.widget.LinearLayout
import androidx.appcompat.widget.AppCompatImageView
import androidx.core.view.ViewCompat
import kotlin.math.abs
import kotlin.math.max

class DragView2 : LinearLayout {


    private var lastDownRawX = 0f
    private var lastDownRawY = 0f

    private var oldDownRawX = 0f
    private var oldDownRawY = 0f
    private var touchSlop: Int = 0

    private var mDragImage: ImageView? = null


    public interface OnViewClickCallback {
        fun onClose(childView: View)
        fun onParentClick(parentView: View)

    }

    private var mOnViewClickCallback: OnViewClickCallback? = null

    public fun setOnViewClickCallback(callback: OnViewClickCallback) {
        this.mOnViewClickCallback = callback
    }

    constructor(context: Context?) : this(context, null)
    constructor(context: Context?, attrs: AttributeSet?) : this(context, attrs, 0)
    constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int) : super(
        context,
        attrs,
        defStyleAttr
    ) {
        orientation = LinearLayout.VERTICAL
        gravity = Gravity.CENTER_HORIZONTAL
        touchSlop = ViewConfiguration.get(context!!).scaledTouchSlop
    }


    override fun onAttachedToWindow() {
        super.onAttachedToWindow()
        for (index in 0 until childCount) {
            val child = getChildAt(index)
            if (child is AppCompatImageView && child.tag == "main_image") {
                mDragImage = child
                continue
            }
            if (child.isClickable && child.tag == "close") {
                child.setOnClickListener {
                    if (null != mOnViewClickCallback) {
                        mOnViewClickCallback?.onClose(child)
                    }
                }
            }
            // 如果你的子view还有别的行为，在xml中给子view加个tag，在这里加逻辑

        }
        setOnClickListener {
            if (null != mOnViewClickCallback) {
                mOnViewClickCallback?.onParentClick(this@DragView2)
            }
        }
    }


    private fun log(msg: String) {
        Log.i("DragView2", msg)
    }

    override fun dispatchTouchEvent(event: MotionEvent): Boolean {
        when (event.action) {


            MotionEvent.ACTION_MOVE -> {
                if (!checkTouchValidate(event)) {
                    log("dispatchTouchEvent#ACTION_MOVE,超出view区域了")
                    alignToHorizontalEdge()
                    return false
                }
            }

        }
        return super.dispatchTouchEvent(event)
    }


    override fun onTouchEvent(event: MotionEvent): Boolean {

        when (event.action) {

            MotionEvent.ACTION_DOWN -> {

                lastDownRawX = event.rawX
                lastDownRawY = event.rawY

                oldDownRawX = lastDownRawX
                oldDownRawY = lastDownRawY
            }


            MotionEvent.ACTION_MOVE -> {

                val moveRawX = event.rawX
                val moveRawY = event.rawY

                val diffRawX = moveRawX - lastDownRawX
                val diffRawY = moveRawY - lastDownRawY

                // move的时候要做边界做个约束
                var leftEdge = (left + diffRawX).toInt()
                // 左边界约束
                if (leftEdge < 0) leftEdge = 0
                val p = parent as ViewGroup
                // 右边界约束
                var rightEdge = leftEdge + width
                if (rightEdge >= p.width) {
                    leftEdge = p.width - width
                    rightEdge = p.width
                }

                // 上边界约束
                var topEdge = (top + diffRawY).toInt()
                if (topEdge < 0)
                    topEdge = 0

                // 下边界约束
                var bottomEdge = topEdge + height
                if (bottomEdge >= p.height) {
                    bottomEdge = p.height
                    topEdge = p.height - height
                }

                ViewCompat.postOnAnimation(this) {
                    layout(
                        leftEdge,
                        topEdge,
                        rightEdge,
                        bottomEdge
                    )
                }
                lastDownRawX = moveRawX
                lastDownRawY = moveRawY
            }

            MotionEvent.ACTION_CANCEL,
            MotionEvent.ACTION_UP -> {
                // 没有超过最小滑动距离就认为是点击事件，避免点击跳转行为失效
                if (abs(lastDownRawY - oldDownRawY) < touchSlop && abs(lastDownRawX - oldDownRawX) < touchSlop) {
                    performClick()
                } else {
                    alignToHorizontalEdge()
                }

                oldDownRawX = 0f
                lastDownRawX = 0f
                oldDownRawY = 0f
                lastDownRawY = 0f
            }
        }

        return true
    }

    private fun alignToHorizontalEdge() {
        val p = parent as ViewGroup
        val centerX = left + width / 2
        if (centerX < p.width / 2) {
            // 靠左停留
            val animator = ValueAnimator()
            animator.setTarget(this)
            //拖拽view到一定位置松手释放时，记录其left；每次拖拽后释放，其left均不同；
            // 对于在不同left释放时，动态调整动画时长，动画效果不会过快或过慢。
            val animationDuration = max(left / 100 * 50, 50).toLong()
            animator.duration = animationDuration
            animator.interpolator = LinearInterpolator()
            //view起始和结束的位置取值
            animator.setIntValues(left, 0)
            animator.addUpdateListener {
                val animatedValue = it.animatedValue as Int
                layout(
                    animatedValue,
                    top,
                    animatedValue + width,
                    top + height
                )
            }
            animator.start()
        } else {
            // 靠右停留
            val valueAnimator = ValueAnimator()
            valueAnimator.setTarget(this)
            valueAnimator.duration = max(50, (p.width - right) / 100 * 50).toLong()
            valueAnimator.setIntValues(right, p.width)
            valueAnimator.interpolator = LinearInterpolator()
            valueAnimator.addUpdateListener {
                val animatedValue = it.animatedValue as Int
                layout(
                    animatedValue - width,
                    top,
                    animatedValue,
                    top + height
                )
            }
            valueAnimator.start()
        }
    }

    /**
     * 检测手指是否还在view上
     */
    private fun checkTouchValidate(event: MotionEvent): Boolean {
        return event.x > 0 && event.x < width && event.y > 0 && event.y < height
    }

    override fun performClick(): Boolean {
        println("-------performClick----------")
        return super.performClick()
    }


}